//
// Created by dell on 2019/5/20.
//
#include <sys/epoll.h>
#include <sys/wait.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <errno.h>

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <android/log.h>

#include "event_obs.h"

int fnode;
int ep_fd;
static struct epoll_event ep_events[1];

void epoll_register(int epoll_fd, int fd) {
  struct epoll_event ev;
  int ret;
  ev.events = EPOLLIN;//interested in receiving data
  ev.data.fd = fd;
  do {
    //register events for fd
    ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
  } while (ret < 0 && errno == EINTR);
}

void epoll_unregister(int epoll_fd, int fd) {
  int ret;
  do {
    ret = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
  } while (ret < 0 && errno == EINTR);
}

int init_event_obs() {

  fnode = open(DEV_INPUT_EVENT_NODE, O_RDWR);
  if (fnode < 0) {
    printf("open %s err %d\n", DEV_INPUT_EVENT_NODE, fnode);
    printf("err: %s\n", strerror(errno));
    return fnode;
  }

  ep_fd = epoll_create(1);
  if (ep_fd < 0) {
    return ep_fd;
  }

  epoll_register(ep_fd, fnode);
  return 0;
}

void destroy_event_obs() {
  epoll_unregister(ep_fd, fnode);
  close(fnode);
}

int getKeyEvent(Key_Event *kevent, int timeOut) {
  struct input_event event;
  int ret = epoll_wait(ep_fd, ep_events, 1, timeOut);//检测是否有事件发生
  if (ret == -1) {
    return ret;
  }
//  printf("getKeyEvent ret = %d \n", ret);

  if (ep_events[0].data.fd == fnode) {
    ret = (int) read(fnode, &event, sizeof(event));
    if (ret > 0) {
      if (event.type == EV_KEY) {
        kevent->code = event.code;
        kevent->value = event.value;
        kevent->node = DEV_INPUT_EVENT_NODE;
        return 1;
      }
    }
  }
  return ret;
}
